package com.example.test_demo.moniMQ;
/**
 * 消息存放队列类
 * @author Hasee
 *
 */

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Store {
	//仓库store最大的存储量
	private int size;
	//锁lock
	private Lock lock;
	//创建2个线程管理工具，管理线程的休眠和唤醒
	private Condition product;//store不能满，满了催眠生产者唤醒消费者线程(消费者线程)
	private Condition consumer;//store不能空，空了唤醒生产者催眠消费者线程(生产者线程)
	private LinkedList<String> storeProduct;//链表队列存储产品
	public Store(int size) {
		super();
		this.size = size;
		lock = new ReentrantLock();
		product =lock.newCondition();
		consumer =lock.newCondition();
		storeProduct= new LinkedList<String>();
	}
	//添加产品
	public void  addProduct() {
		// TODO Auto-generated method stub

		try {
			//枷锁保证安全
			//lock.lock();//这个锁与synchronized无异，获取不到锁 线程会一直等到容易造成死锁
			//trylock的总用就是：获取锁返回true，获取不到锁返回false，这样可以避免线程的等待，让它可以去干别的工作
			//重点：1）这里使用lock()而不用trylock(),因为trylock获取不到锁线程无法等待无法await  2）await的线程一定要用signal唤醒，notify不行
			lock.lock();;
			//当list的size()==size时就不再生产了
			while (storeProduct.size()==size) {
				System.out.println("爆仓了，停一下");
				product.await();
			}
			//如果队列size()小于store的最大库存size，就往队列list中添加，否则终止线程
			storeProduct.add("商品");
			System.out.println("线程："+Thread.currentThread().getName()+"put进仓库"+storeProduct.size()+"件产品");


			//消费者消费产品
			//signalAll作用 是唤醒在次lock对象上等待的所有线程
			consumer.signalAll();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//需要手动释放锁，否则会造成死锁
			lock.unlock();
		}

	}
	//消费产品
	public void deleProduct() {
		// TODO Auto-generated method stub

		try {
			//枷锁保证安全
			//lock.lock();//这个锁与synchronized无异，获取不到锁 线程会一直等到容易造成死锁
			//trylock的总用就是：获取锁返回true，获取不到锁返回false，这样可以避免线程的等待，让它可以去干别的工作
			lock.lock();;
			//当list的size()==size时就不再生产了
			while (storeProduct.size()==0) {
				System.out.println("0库存，停止消费");
				consumer.await();
			}
			//清仓
			storeProduct.poll();
			System.out.println("线程："+Thread.currentThread().getName()+"消费产品，仓库剩余"+storeProduct.size()+"件产品");


			//消费中，并通知生产者生产
			product.signalAll();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//需要手动释放锁，否则会造成死锁
			lock.unlock();
		}
	}

}
